<script lang="tsx">
    import type { PropType } from 'vue';
    import { Result, Button } from 'ant-design-vue';
    import { defineComponent, ref, computed, unref } from 'vue';
    import { ExceptionEnum } from '/@/enums/exceptionEnum';
    import notDataSvg from '/@/assets/svg/no-data.svg';
    import netWorkSvg from '/@/assets/svg/net-error.svg';
    import { useRoute } from 'vue-router';
    import { useDesign } from '/@/hooks/web/useDesign';
    import { useI18n } from '/@/hooks/web/useI18n';
    import { useGo, useRedo } from '/@/hooks/web/usePage';
    import { PageEnum } from '/@/enums/pageEnum';

    interface MapValue {
        title: string;
        subTitle: string;
        btnText?: string;
        icon?: string;
        handler?: Fn;
        status?: string;
    }

    export default defineComponent({
        name: 'ErrorPage',
        props: {
            // 状态码
            status: {
                type: Number as PropType<number>,
                default: ExceptionEnum.PAGE_NOT_FOUND,
            },

            title: {
                type: String as PropType<string>,
                default: '',
            },

            subTitle: {
                type: String as PropType<string>,
                default: '',
            },

            full: {
                type: Boolean as PropType<boolean>,
                default: false,
            },
        },
        setup(props) {
            const statusMapRef = ref(new Map<string | number, MapValue>());

            const { query } = useRoute();
            const go = useGo();
            const redo = useRedo();
            const { t } = useI18n();
            const { prefixCls } = useDesign('app-exception-page');

            const getStatus = computed(() => {
                const { status: routeStatus } = query;
                const { status } = props;
                return Number(routeStatus) || status;
            });

            const getMapValue = computed((): MapValue => {
                return unref(statusMapRef).get(unref(getStatus)) as MapValue;
            });

            const backLoginI18n = t('sys.exception.backLogin');
            const backHomeI18n = t('sys.exception.backHome');

            unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_ACCESS, {
                title: '403',
                status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
                subTitle: t('sys.exception.subTitle403'),
                btnText: props.full ? backLoginI18n : backHomeI18n,
                handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
            });

            unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_FOUND, {
                title: '404',
                status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
                subTitle: t('sys.exception.subTitle404'),
                btnText: props.full ? backLoginI18n : backHomeI18n,
                handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
            });

            unref(statusMapRef).set(ExceptionEnum.ERROR, {
                title: '500',
                status: `${ExceptionEnum.ERROR}`,
                subTitle: t('sys.exception.subTitle500'),
                btnText: backHomeI18n,
                handler: () => go(),
            });

            unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_DATA, {
                title: t('sys.exception.noDataTitle'),
                subTitle: '',
                btnText: t('common.redo'),
                handler: () => redo(),
                icon: notDataSvg,
            });

            unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, {
                title: t('sys.exception.networkErrorTitle'),
                subTitle: t('sys.exception.networkErrorSubTitle'),
                btnText: t('common.redo'),
                handler: () => redo(),
                icon: netWorkSvg,
            });

            return () => {
                const { title, subTitle, btnText, icon, handler, status } = unref(getMapValue) || {};
                return (
                    <Result
                        class={prefixCls}
                        status={status as any}
                        title={props.title || title}
                        sub-title={props.subTitle || subTitle}
                    >
                        {{
                            extra: () =>
                                btnText && (
                                    <Button type="primary" onClick={handler}>
                                        {() => btnText}
                                    </Button>
                                ),
                            icon: () => (icon ? <img src={icon} /> : null),
                        }}
                    </Result>
                );
            };
        },
    });
</script>
<style lang="less">
    @prefix-cls: ~'@{namespace}-app-exception-page';

    .@{prefix-cls} {
        display: flex;
        align-items: center;
        flex-direction: column;

        .ant-result-icon {
            img {
                max-width: 400px;
                max-height: 300px;
            }
        }
    }
</style>
